using System;
using System.IO;
using System.Xml;
using System.Data;
using System.Drawing;
using System.Reflection;
using System.Collections;
using System.Globalization;
using System.Security.Permissions;
using System.ComponentModel;
using System.Windows.Forms;
using needle.UI.Controls.Flat.Resources;
using needle.UI.Controls.Flat.Resources.Keys;
using needle.UI.Controls.Flat.Utilities.Drawing;
using needle.UI.Controls.Flat.Windows.Forms;
using needle.UI.Controls.Flat.Windows.Forms.Helpers;
using needle.UI.Controls.Flat.Windows.Forms.Collections;

namespace needle.UI.Controls.Flat.Windows.Forms
{
	public class TabGroupLeaf : TabGroupBase
	{
	    protected const int mimageWidth = 16;
        protected const int mimageHeight = 16;
        protected const int mimageHorzSplit = 0;
        protected const int mimageVertSplit = 1;
	
        protected static ImageList minternalImages;
        
		protected MenuItem mmcClose;
        protected MenuItem mmcSep1;
        protected MenuItem mmcProm;
        protected MenuItem mmcReba;
        protected MenuItem mmcSep2;
        protected MenuItem mmcPrev;
        protected MenuItem mmcNext;
        protected MenuItem mmcVert;
        protected MenuItem mmcHorz;

        protected Cursor msavedCursor;
        protected bool mdragEntered;
        protected TargetManager mtargetManager;
        protected needle.UI.Controls.Flat.Windows.Forms.TabControl mtabControl;

		#region Constructors
		
		static TabGroupLeaf()
        {
            minternalImages = DrawHelpers.LoadBitmapStrip(Type.GetType("needle.UI.Controls.Flat.Windows.Forms.TabbedGroups"),
                                                             "needle.UI.Controls.Flat.Windows.Forms.Resources.ImagesTabbedGroups.bmp",
                                                             new Size(mimageWidth, mimageHeight),
                                                             new Point(0,0));
        }
	
		public TabGroupLeaf(TabbedGroups tabbedGroups, TabGroupBase parent)
		    : base(tabbedGroups, parent)
		{
		    mtabControl = new needle.UI.Controls.Flat.Windows.Forms.TabControl();
		    
		    mtabControl.DragFromControl = false;
		    
            mdragEntered = false;
            mtabControl.AllowDrop = true;
            mtabControl.DragDrop += new DragEventHandler(OnControlDragDrop);
            mtabControl.DragEnter += new DragEventHandler(OnControlDragEnter);
            mtabControl.DragLeave += new EventHandler(OnControlDragLeave);
		    
            mtabControl.PageDragStart += new MouseEventHandler(OnPageDragStart);
            mtabControl.PageDragMove += new MouseEventHandler(OnPageDragMove);
            mtabControl.PageDragEnd += new MouseEventHandler(OnPageDragEnd);
            mtabControl.PageDragQuit += new MouseEventHandler(OnPageDragQuit);
		    
            mtabControl.TabPages.Cleared += new CollectionClearEventHandler(OnTabPagesCleared);
            mtabControl.TabPages.Inserted += new needle.UI.Controls.Flat.Windows.Forms.Collections.CollectionChangeEventHandler(OnTabPagesInserted);
            mtabControl.TabPages.Removed += new needle.UI.Controls.Flat.Windows.Forms.Collections.CollectionChangeEventHandler(OnTabPagesRemoved);
            
            mtabControl.GotFocus += new EventHandler(OnGainedFocus);
            mtabControl.PageGotFocus += new EventHandler(OnGainedFocus);
            mtabControl.ClosePressed += new EventHandler(OnClose);            
            
            mtargetManager = null;
            
            DefinePopupMenuForControl(mtabControl);

            Notify(TabGroupBase.NotifyCode.DisplayTabMode);

		    mtabbedGroups.OnTabControlCreated(new TabbedGroups.TabControlCreatedEventArgs(mtabControl));
		}

		#endregion

		#region Dispose
		
		public override void Dispose()
		{
			/*mmcClose.Click -= new EventHandler(OnClose);
			mmcProm.Click -= new EventHandler(OnToggleProminent);
			mmcReba.Click -= new EventHandler(OnRebalance);
			mmcHorz.Click -= new EventHandler(OnNewVertical);
			mmcVert.Click -= new EventHandler(OnNewHorizontal);
			mmcNext.Click -= new EventHandler(OnMoveNext);
			mmcPrev.Click -= new EventHandler(OnMovePrevious);*/
			
			if (mtabControl != null)
			{
				mtabControl.DragDrop -= new DragEventHandler(OnControlDragDrop);
				mtabControl.DragEnter -= new DragEventHandler(OnControlDragEnter);
				mtabControl.DragLeave -= new EventHandler(OnControlDragLeave);

				mtabControl.PageDragStart -= new MouseEventHandler(OnPageDragStart);
				mtabControl.PageDragMove -= new MouseEventHandler(OnPageDragMove);
				mtabControl.PageDragEnd -= new MouseEventHandler(OnPageDragEnd);
				mtabControl.PageDragQuit -= new MouseEventHandler(OnPageDragQuit);

				mtabControl.TabPages.Cleared -= new CollectionClearEventHandler(OnTabPagesCleared);
				mtabControl.TabPages.Inserted -= new needle.UI.Controls.Flat.Windows.Forms.Collections.CollectionChangeEventHandler(OnTabPagesInserted);
				mtabControl.TabPages.Removed -= new needle.UI.Controls.Flat.Windows.Forms.Collections.CollectionChangeEventHandler(OnTabPagesRemoved);

				mtabControl.GotFocus -= new EventHandler(OnGainedFocus);
				mtabControl.PageGotFocus -= new EventHandler(OnGainedFocus);
				mtabControl.ClosePressed -= new EventHandler(OnClose);            
				mtabControl.PopupMenuDisplay -= new CancelEventHandler(OnPopupMenuDisplay);

				ControlUtilities.RemoveAll(mtabControl);

				mtabControl.Dispose();
				mtabControl = null;
			}

			//this.Dispose();
		}

		#endregion

		#region Virtuals

		protected void DefinePopupMenuForControl(needle.UI.Controls.Flat.Windows.Forms.TabControl tabControl)
        {
            ContextMenu pm = new ContextMenu();
            
            mmcClose = new MenuItem("", new EventHandler(OnClose));
            mmcSep1 = new MenuItem("-");
            mmcProm = new MenuItem("", new EventHandler(OnToggleProminent));
            mmcReba = new MenuItem("", new EventHandler(OnRebalance));
            mmcSep2 = new MenuItem("-");
            mmcHorz = new MenuItem("", new EventHandler(OnNewVertical));
            mmcVert = new MenuItem("", new EventHandler(OnNewHorizontal));
            mmcNext = new MenuItem("", new EventHandler(OnMoveNext));
            mmcPrev = new MenuItem("", new EventHandler(OnMovePrevious));

            mmcProm.RadioCheck = true;

            tabControl.ContextMenu = pm;

            tabControl.PopupMenuDisplay += new CancelEventHandler(OnPopupMenuDisplay);
        }

		protected void AddGroupToSequence(TabGroupSequence tgs, TabGroupLeaf sourceLeaf, bool before)
		{
			bool autoCompact = mtabbedGroups.AutoCompact;

			mtabbedGroups.AutoCompact = false;

			int pos = tgs.IndexOf(this);
                
			TabGroupLeaf newGroup = null;

			if (before)
				newGroup = tgs.InsertNewLeaf(pos);
			else
			{
				if (pos == (tgs.Count - 1))
					newGroup = tgs.AddNewLeaf();
				else
					newGroup = tgs.InsertNewLeaf(pos + 1);
			}
                     
			needle.UI.Controls.Flat.Windows.Forms.TabControl tc = sourceLeaf.GrouparamControl as needle.UI.Controls.Flat.Windows.Forms.TabControl;
                        
			TabPage tp = tc.SelectedTab;

			tc.TabPages.Remove(tp);
                    
			newGroup.TabPages.Add(tp);

			mtabbedGroups.AutoCompact = autoCompact;

			if (mtabbedGroups.AutoCompact)
				mtabbedGroups.Compact();
		}
        
		protected void OnPageDragStart(object sender, MouseEventArgs e)
		{
			if (!mtabbedGroups.LayoutLock)
			{        
				msavedCursor = mtabControl.Cursor;
				mtargetManager = new TargetManager(mtabbedGroups, this, mtabControl);
			}
		}
 
		protected void OnPageDragMove(object sender, MouseEventArgs e)
		{
			if (!mtabbedGroups.LayoutLock)
			{        
				Point mousePos = mtabControl.PointToScreen(new Point(e.X, e.Y));

				mtargetManager.MouseMove(mousePos);
			}
		}

		protected void OnPageDragEnd(object sender, MouseEventArgs e)
		{
			if (!mtabbedGroups.LayoutLock)
			{        
				mtargetManager.Exit();

				mtargetManager = null;
	            
				if (mtabControl != null)
				{
					mtabControl.Cursor = msavedCursor;
				}
			}
		}

		protected void OnPageDragQuit(object sender, MouseEventArgs e)
		{
			if (!mtabbedGroups.LayoutLock)
			{        
				mtargetManager.Quit();
	        
				mtargetManager = null;

				mtabControl.Cursor = msavedCursor;
			}
		}

		protected void OnControlDragEnter(object sender, DragEventArgs drgevent)
		{
			if (!mtabbedGroups.LayoutLock)
			{        
				mdragEntered = ValidFormat(drgevent);
        
				if (mdragEntered)
				{
					DrawDragIndicator();
	                
					drgevent.Effect = DragDropEffects.Copy;
				}
			}
			else
			{
				drgevent.Effect = DragDropEffects.None;
			}
		}

		protected void OnControlDragDrop(object sender, DragEventArgs drgevent)
		{
			if (mdragEntered)
			{
				DrawDragIndicator();
				mtabbedGroups.OnExternalDrop(new TabbedGroups.ExternalDropEventArgs(this, mtabControl, GetDragProvider(drgevent)));
			}

			mdragEntered = false;
		}

		protected void OnControlDragLeave(object sender, EventArgs e)
		{
			if (mdragEntered)
				DrawDragIndicator();
                
			mdragEntered = false;
		}
        
		protected bool ValidFormat(DragEventArgs e)
		{
			return e.Data.GetDataPresent(typeof(TabbedGroups.DragProvider));
		}
        
		protected TabbedGroups.DragProvider GetDragProvider(DragEventArgs e)
		{
			return (TabbedGroups.DragProvider)e.Data.GetData(typeof(TabbedGroups.DragProvider));
		}
        
		protected void DrawDragIndicator()
		{
			Rectangle clientRect = new Rectangle(new Point(0,0), mtabControl.ClientSize);
			TargetManager.DrawDragRectangle(mtabControl.RectangleToScreen(clientRect));
		}

		protected void OnNewHorizontal(object sender, EventArgs e)
		{
			NewHorizontalGroup(this, false);    
		}

		protected void OnGainedFocus(object sender, EventArgs e)
		{
			mtabbedGroups.ActiveLeaf = this;
		}

		protected void OnTabPagesCleared(object sender, EventArgs e)
		{
			if (mtabbedGroups.AutoCompact)
				mtabbedGroups.Compact();

			if (mtabbedGroups.AutoCalculateDirty)
				mtabbedGroups.Dirty = true;
		}

		protected void OnTabPagesInserted(object sender, needle.UI.Controls.Flat.Windows.Forms.Collections.CollectionChangeEventArgs e)
		{
			if (mtabbedGroups.ActiveLeaf == null)
				mtabbedGroups.ActiveLeaf = this;

			if (mtabbedGroups.AutoCalculateDirty)
				mtabbedGroups.Dirty = true;
		}

		protected void OnTabPagesRemoved(object sender, needle.UI.Controls.Flat.Windows.Forms.Collections.CollectionChangeEventArgs e)
		{
			if (mtabControl.TabPages.Count == 0)
			{
				if (mtabbedGroups.AutoCompact)
					mtabbedGroups.Compact();
			}

			if (mtabbedGroups.AutoCalculateDirty)
				mtabbedGroups.Dirty = true;
		}
        
		protected void OnPopupMenuDisplay(object sender, CancelEventArgs e)
		{
			mtabControl.ContextMenu.MenuItems.Clear();
            
			mtabControl.ContextMenu.MenuItems.AddRange(new MenuItem[]{mmcClose, mmcSep1, 
													   	              mmcProm, mmcReba, 
																	  mmcSep2, mmcHorz, 
																	  mmcVert, mmcNext, 
																	  mmcPrev});
			if (!mtabbedGroups.LayoutLock)
			{        
				bool valid = (mtabControl.SelectedIndex != -1);
	        
				mmcClose.Text = mtabbedGroups.CloseMenuText;
				mmcProm.Text = mtabbedGroups.ProminentMenuText;
				mmcReba.Text = mtabbedGroups.RebalanceMenuText;
				mmcPrev.Text = mtabbedGroups.MovePreviousMenuText;
				mmcNext.Text = mtabbedGroups.MoveNextMenuText;
				mmcVert.Text = mtabbedGroups.NewVerticalMenuText;
				mmcHorz.Text = mtabbedGroups.NewHorizontalMenuText;
	            
				mmcClose.Visible = mtabControl.ShowClose && valid;
				mmcSep1.Visible = mtabControl.ShowClose && valid;
	            
				mmcProm.Checked = (mtabbedGroups.ProminentLeaf == this);
	            
				bool split = valid && (mtabControl.TabPages.Count > 1);

				bool vertSplit = split;
				bool horzSplit = split;
	            
				TabGroupSequence tgs = mparent as TabGroupSequence;

				if (tgs.Count > 1)
				{
					if (tgs.Direction == Direction.Vertical)
						vertSplit = false;
					else
						horzSplit = false;
				}
	            
				mmcVert.Visible = vertSplit;
				mmcHorz.Visible = horzSplit;

				mmcNext.Visible = valid && (mtabbedGroups.NextLeaf(this) != null);
				mmcPrev.Visible = valid && (mtabbedGroups.PreviousLeaf(this) != null);
				mmcSep2.Visible = mmcNext.Visible | mmcPrev.Visible | vertSplit | horzSplit;
			}
			else
			{
				mmcClose.Visible = false;
				mmcProm.Visible = false;
				mmcReba.Visible = false;
				mmcPrev.Visible = false;
				mmcNext.Visible = false;
				mmcVert.Visible = false;
				mmcHorz.Visible = false;
				mmcSep1.Visible = false;
				mmcSep2.Visible = false;
			}

			TabbedGroupsContextMenuEventArgs tge = new TabbedGroupsContextMenuEventArgs(this, 
				mtabControl, 
				mtabControl.SelectedTab,
				mtabControl.ContextMenu);
        
			mtabbedGroups.OnPageContextMenu(tge);
            
			int visibleCommands = 0;
            
			foreach(MenuItem mc in mtabControl.ContextMenu.MenuItems)
				if (mc.Visible)
					visibleCommands++;
            
			e.Cancel = (tge.Cancel || (visibleCommands == 0));
		}

		#endregion 
    
		#region Overrides

        public override void Notify(NotifyCode code)
        {
            switch(code)
            {
                case NotifyCode.ImageListChanging:
                    if (mtabbedGroups.ImageList == mtabControl.ImageList)
                    {   
                        mtabControl.ImageList = null;
                    }
                    break;
                case NotifyCode.ImageListChanged:
                    if (mtabControl.ImageList == null)
                    {   
                        mtabControl.ImageList = mtabbedGroups.ImageList;
                    }
                    break;
                case NotifyCode.DisplayTabMode:
                    switch(mtabbedGroups.DisplayTabMode)
                    {
                        case needle.UI.Controls.Flat.Windows.Forms.TabbedGroups.DisplayTabModes.ShowAll:
                            mtabControl.HideTabsMode = needle.UI.Controls.Flat.Windows.Forms.TabControl.HideTabsModes.ShowAlways;
                            break;
                        case needle.UI.Controls.Flat.Windows.Forms.TabbedGroups.DisplayTabModes.HideAll:
                            mtabControl.HideTabsMode = needle.UI.Controls.Flat.Windows.Forms.TabControl.HideTabsModes.HideAlways;
                            break;
                        case needle.UI.Controls.Flat.Windows.Forms.TabbedGroups.DisplayTabModes.ShowActiveLeaf:
                            mtabControl.HideTabsMode = (mtabbedGroups.ActiveLeaf == this ? needle.UI.Controls.Flat.Windows.Forms.TabControl.HideTabsModes.ShowAlways :
                                                                                           needle.UI.Controls.Flat.Windows.Forms.TabControl.HideTabsModes.HideAlways);
                            break;
                        case needle.UI.Controls.Flat.Windows.Forms.TabbedGroups.DisplayTabModes.ShowMouseOver:
                            mtabControl.HideTabsMode = needle.UI.Controls.Flat.Windows.Forms.TabControl.HideTabsModes.HideWithoutMouse;
                            break;
                        case needle.UI.Controls.Flat.Windows.Forms.TabbedGroups.DisplayTabModes.ShowActiveAndMouseOver:
                            mtabControl.HideTabsMode = (mtabbedGroups.ActiveLeaf == this ? needle.UI.Controls.Flat.Windows.Forms.TabControl.HideTabsModes.ShowAlways :
                                                                                           needle.UI.Controls.Flat.Windows.Forms.TabControl.HideTabsModes.HideWithoutMouse);
                            break;
                    }
                    break;
            }
        }

        public override int Count               { get { return mtabControl.TabPages.Count; } }
        public override bool IsLeaf             { get { return true; } }
        public override bool IsSequence         { get { return false; } }
        public override Control GrouparamControl    { get { return mtabControl; } }
        
        public override bool ContainsProminent(bool recurse)
        {
            TabGroupLeaf prominent = mtabbedGroups.ProminentLeaf;

            if (prominent != null)
                return (this == prominent);
            else
                return false;
        }

        public override void SaveToXml(XmlTextWriter xmlOut)
        {
            xmlOut.WriteStartElement("Leaf");
            xmlOut.WriteAttributeString("Count", Count.ToString(CultureInfo.CurrentCulture));
            xmlOut.WriteAttributeString("Unique", munique.ToString(CultureInfo.CurrentCulture));
            xmlOut.WriteAttributeString("Space", mspace.ToString(CultureInfo.CurrentCulture));

            foreach(needle.UI.Controls.Flat.Windows.Forms.TabPage tp in mtabControl.TabPages)
            {
                string controlType = "null";
                
				if (mtabbedGroups.SaveControls && tp.Control != null)
					controlType = tp.Control.GetType().AssemblyQualifiedName;
				
                xmlOut.WriteStartElement("Page");
                xmlOut.WriteAttributeString("Title", tp.Title);
                xmlOut.WriteAttributeString("ImageList", (tp.ImageList != null).ToString(CultureInfo.CurrentCulture));
                xmlOut.WriteAttributeString("ImageIndex", tp.ImageIndex.ToString(CultureInfo.CurrentCulture));
                xmlOut.WriteAttributeString("Selected", tp.Selected.ToString(CultureInfo.CurrentCulture));
                xmlOut.WriteAttributeString("Control", controlType);

                xmlOut.WriteStartElement("CustomPageData");
                mtabbedGroups.OnPageSaving(new TabbedGroupsPageSavingEventArgs(tp, xmlOut));
                xmlOut.WriteEndElement();

                xmlOut.WriteEndElement();
            }
                
            xmlOut.WriteEndElement();
        }

        [SecurityPermission(SecurityAction.Demand)]
		public override void LoadFromXml(XmlTextReader xmlIn)
        {
            string rawCount = xmlIn.GetAttribute(0);
            string rawUnique = xmlIn.GetAttribute(1);
            string rawSpace = xmlIn.GetAttribute(2);

            int count = Convert.ToInt32(rawCount, CultureInfo.CurrentCulture);
            int unique = Convert.ToInt32(rawUnique, CultureInfo.CurrentCulture);
            Decimal space = Convert.ToDecimal(rawSpace, CultureInfo.CurrentCulture);
            
            munique = unique;
            mspace = space;
            
            for(int i=0; i<count; i++)
            {
                if (!xmlIn.Read())
                    throw new ArgumentException(ResourceLibrary.GetString(WindowsControlsResourceKeys.InaccessibleNode, WindowsControlsResourceKeys.Root));

                if (xmlIn.Name == "Page")
                {
                    needle.UI.Controls.Flat.Windows.Forms.TabPage tp = new needle.UI.Controls.Flat.Windows.Forms.TabPage();

                    string title = xmlIn.GetAttribute(0);
                    string rawImageList = xmlIn.GetAttribute(1);
                    string rawImageIndex = xmlIn.GetAttribute(2);
                    string rawSelected = xmlIn.GetAttribute(3);
                    string controlType = xmlIn.GetAttribute(4);

                    bool imageList = Convert.ToBoolean(rawImageList, CultureInfo.CurrentCulture);
                    int imageIndex = Convert.ToInt32(rawImageIndex, CultureInfo.CurrentCulture);
                    bool selected = Convert.ToBoolean(rawSelected, CultureInfo.CurrentCulture);

                    tp.Title = title;
                    tp.ImageIndex = imageIndex;
                    tp.Selected = selected;
                    
                    if (imageList)
                        tp.ImageList = mtabbedGroups.ImageList;
                    
                    if (controlType != "null")
                    {
                        try
                        {
                            Type t = Type.GetType(controlType);
                            
                            if (t != null)
                            {
                                Assembly a = t.Assembly;
                                
                                if (a != null)
                                {
                                    object newObj = a.CreateInstance(t.FullName, true, BindingFlags.Default, null, null, CultureInfo.CurrentCulture, null);
                                    
                                    Control newControl = newObj as Control;
                                    
                                    if (newControl != null)
                                        tp.Control = newControl;
                                }
                            }
                        }
                        catch
                        {
                        }
                    }
                    
                    if (!xmlIn.Read())
                        throw new ArgumentException(ResourceLibrary.GetString(WindowsControlsResourceKeys.InaccessibleNode, WindowsControlsResourceKeys.Root));

                    if (xmlIn.Name != "CustomPageData")
                        throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, ResourceLibrary.GetString(WindowsControlsResourceKeys.ElementNotFound, WindowsControlsResourceKeys.Root), "CustomPageData"));

                    bool finished = xmlIn.IsEmptyElement;

                    TabbedGroupsPageLoadingEventArgs e = new TabbedGroupsPageLoadingEventArgs(tp, xmlIn);

                    mtabbedGroups.OnPageLoading(e);
                    
                    if (!e.Cancel)
                        mtabControl.TabPages.Add(tp);
                    
                    while(!finished)
                    {
                        if (xmlIn.NodeType == XmlNodeType.EndElement)
                            finished = (xmlIn.Name == "CustomPageData");

                        if (!finished)
                        {
                            if (!xmlIn.Read())
                                throw new ArgumentException(ResourceLibrary.GetString(WindowsControlsResourceKeys.InaccessibleNode, WindowsControlsResourceKeys.Root));
                        }
                    } 

                    if (!xmlIn.Read())
                        throw new ArgumentException(ResourceLibrary.GetString(WindowsControlsResourceKeys.InaccessibleNode, WindowsControlsResourceKeys.Root));

                    if (xmlIn.NodeType != XmlNodeType.EndElement)
                        throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, ResourceLibrary.GetString(WindowsControlsResourceKeys.ElementNotFound, WindowsControlsResourceKeys.Root), "Page"));
                    
                }
                else
                    throw new ArgumentException(ResourceLibrary.GetString(WindowsControlsResourceKeys.InaccessibleNode, WindowsControlsResourceKeys.Root));
            }
        }

		#endregion

		#region Methods
        
        internal void OnClose(object sender, EventArgs e)
        {
			if ((mtabControl.TabPages.Count > 0) || mtabbedGroups.PageCloseWhenEmpty)
			{
				TabbedGroupsCloseRequestEventArgs tge = new TabbedGroupsCloseRequestEventArgs(this, mtabControl, mtabControl.SelectedTab);
            
				mtabbedGroups.OnPageCloseRequested(tge);
                
				if (!tge.Cancel && (mtabControl.TabPages.Count > 0))
					mtabControl.TabPages.Remove(mtabControl.SelectedTab);
			}			
        }
        
        internal void OnToggleProminent(object sender, EventArgs e)
        {
            if (mtabbedGroups.ProminentLeaf == this)
                mtabbedGroups.ProminentLeaf = null;
            else
                mtabbedGroups.ProminentLeaf = this;
        }

        internal void OnRebalance(object sender, EventArgs e)
        {
            mtabbedGroups.Rebalance();
        }
            
        internal void OnMovePrevious(object sender, EventArgs e)
        {
            TabGroupLeaf prev = mtabbedGroups.PreviousLeaf(this);
            
            if (prev != null)           
                MovePageToLeaf(prev);
        }

        internal void OnMoveNext(object sender, EventArgs e)
        {
            TabGroupLeaf next = mtabbedGroups.NextLeaf(this);
            
            if (next != null)           
                MovePageToLeaf(next);
        }

        internal void OnNewVertical(object sender, EventArgs e)
        {
            NewVerticalGroup(this, false);
        }

        internal void NewVerticalGroup(TabGroupLeaf sourceLeaf, bool before)
        {
            TabGroupSequence tgs = this.Parent as TabGroupSequence;
        
            if (tgs != null)
            {
                tgs.Direction = Direction.Vertical;
                AddGroupToSequence(tgs, sourceLeaf, before);
            }
        }
        
        internal void NewHorizontalGroup(TabGroupLeaf sourceLeaf, bool before)
        {
            TabGroupSequence tgs = this.Parent as TabGroupSequence;
        
            if (tgs != null)
            {
                tgs.Direction = Direction.Horizontal;
                AddGroupToSequence(tgs, sourceLeaf, before);
            }
        }
        
        internal void MovePageToLeaf(TabGroupLeaf leaf)
        {
            bool autoCompact = mtabbedGroups.AutoCompact;

            mtabbedGroups.AutoCompact = false;

            TabPage tp = mtabControl.SelectedTab;

            mtabControl.TabPages.Remove(tp);
            
            leaf.TabPages.Add(tp);

            mtabbedGroups.ActiveLeaf = leaf;
                
            TabControl tc = leaf.GrouparamControl as needle.UI.Controls.Flat.Windows.Forms.TabControl;
                
            tc.SelectedTab = tp;

            mtabbedGroups.AutoCompact = autoCompact;
            
            if (mtabbedGroups.AutoCompact)
                mtabbedGroups.Compact();
        }

		#endregion

		#region Properties

		public TabPageCollection TabPages
		{
			get { return mtabControl.TabPages; }
		}

		#endregion
    }
}
